package vision.nvhuong.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.ejb.HibernateEntityManager;

import vision.nvhuong.dao.BaseDao;


public class BaseDaoJpaImpl<T, PK extends Serializable> implements
	BaseDao<T, PK>{
	
	protected Class<T> entityClass;
	
	@SuppressWarnings("unchecked")
	public BaseDaoJpaImpl() {
		ParameterizedType genericSuperclass = (ParameterizedType) getClass()
				.getGenericSuperclass();
		this.entityClass = (Class<T>) genericSuperclass
				.getActualTypeArguments()[0];

	}

	@Override
	public T persist(T entity, EntityManager em) {
		em.persist(entity);
		return entity;
	}

	@Override
	public T remove(T entity, EntityManager em) {
		reassociate(em, entity);
		em.remove(entity);
		return entity;
	}
	
	private void reassociate(EntityManager em, Object entity) {
		if (!em.contains(entity)) {
			HibernateEntityManager hem = (HibernateEntityManager) em;

			LockOptions lockOptions = new LockOptions(LockMode.NONE);
			hem.getSession().buildLockRequest(lockOptions).lock(entity);
		}
	}

	@Override
	public T refresh(T entity, EntityManager em) {
		reassociate(em, entity);
		em.refresh(entity);
		return entity;
	}

	@Override
	public T findById(PK id, EntityManager em) {
		return em.find(entityClass, id);
	}

	@Override
	public T merge(T entity, EntityManager em) {
		return em.merge(entity);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> findAll(EntityManager em) {
		Query query = em.createQuery("from " + entityClass.getSimpleName());
		return query.getResultList();
	}

	@Override
	public Long getTotalResult(EntityManager em) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<T> persistList(List<T> entityList, EntityManager em) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<T> removeList(List<T> entityList, EntityManager em) {
		// TODO Auto-generated method stub
		return null;
	}

}
